let fs = require("fs");
let path = require("path");
let http = require("http");
let axios = require("axios");
let index = require("../dist/index.js");

let node_funs = {
  ...index,

  // 分系统使用 mac 不行 监听U盘插入或者移除
  // listenUDisk(addFun, removeFun) {
  //   const usbDetect = require("usb-detection"); // u盘监听插件

  //   usbDetect.startMonitoring();

  //   // U盘监听 插入
  //   usbDetect.on("add", function () {
  //     typeof addFun == "function" && addFun(...arguments);
  //   });

  //   // U盘监听 移除
  //   usbDetect.on("remove", function () {
  //     typeof removeFun == "function" && removeFun(...arguments);
  //   });
  // },

  // 延时函数 类似 pyhton sleep
  delay(duration = 1000) {
    const start = Date.now();
    while (Date.now() - start < duration) {}
  },
  sleep(t) {
    return this.delay(t);
  },

  // 去重 合并 指定文件夹下的 多个JSON文件
  mergeFiles(dirPath, frimaryKey) {
    let files = fs.readdirSync(dirPath);
    let end_arr = [];
    files.forEach((item) => {
      let file_path = path.join(dirPath, item);
      let stat = fs.statSync(file_path);
      if (stat.isFile() && path.extname(file_path) == ".json") {
        try {
          let arr = JSON.parse(fs.readFileSync(file_path, "utf-8"));
          end_arr.push(...arr);
        } catch (error) {}

        fs.unlinkSync(file_path);
      }
    });

    fs.writeFileSync(
      path.join(dirPath, "merge.json"),
      JSON.stringify(index.unique(end_arr, frimaryKey), null, 2)
    );
  },

  /**
   * 不递归 查询某文件夹下指定文件类型的文件，返回其相关数据同时按照创建时间进行排序
   * @param {文件夹路径} _p
   * @param {指定文件类型} _file_type_arr
   * @param {正序 倒叙（默认倒叙=desc=后生成的排在前面）} _sorting
   * @returns
   */
  get_target_files(_p, _file_type_arr, _sorting = "desc") {
    let all_files = [];
    try {
      fs.statSync(path.resolve(_p));
    } catch (error) {
      console.error("文件路径读取失败 | Failed to read the specified path");
      return;
    }
    if (!Array.isArray(_file_type_arr)) {
      console.error("类型入参应为数组 | Type parameter must be an array");
      return;
    }
    let temp_files_arr = fs.readdirSync(_p);
    let res_arr = [];
    for (let i = 0; i < temp_files_arr.length; i++) {
      const file_item = temp_files_arr[i];
      let t = "";
      try {
        t = file_item.match(/\.\w+$/)[0].split(".")[1];
      } catch (error) {
        console.error("获取文件类型失败 | Get file type failed");
        continue;
      }
      if (
        !_file_type_arr.length ||
        _file_type_arr.some(
          (item) => String(item).toLowerCase() === String(t).toLowerCase()
        )
      ) {
        let detail = fs.statSync(path.resolve(_p, file_item));
        res_arr.push({
          ...detail,
          name: file_item,
          path: path.resolve(_p, file_item),
          ctimeMs: detail.ctimeMs,
        });
      }
    }

    res_arr.sort((a, b) => {
      if (_sorting && String(_sorting).toLowerCase() === "asc") {
        return a.ctimeMs - b.ctimeMs;
      } else {
        return b.ctimeMs - a.ctimeMs;
      }
    });
    return res_arr;
  },

  // 是否文件夹
  isNotDir(p) {
    if (!fs.existsSync(p)) {
      return false;
    }
    let sd = fs.statSync(p);
    if (sd.isDirectory()) {
      return true;
    } else {
      return false;
    }
  },

  /**
   * 递归 查询某文件夹下指定文件类型的文件，返回其相关数据同时按照创建时间进行排序
   * @param {文件夹路径} _p
   * @param {指定文件类型} _file_type_arr
   * @param {正序 倒叙（默认倒叙=desc=后生成的排在前面）} _sorting
   * @returns
   */
  getTargetFilesByTargetPath(_p, _file_type_arr, _sorting = "desc") {
    let allFiles = [];
    try {
      fs.statSync(path.resolve(_p));
    } catch (error) {
      console.error("文件路径读取失败 | Failed to read the specified path");
      return;
    }
    if (!Array.isArray(_file_type_arr)) {
      console.error("类型入参应为数组 | Type parameter must be an array");
      return;
    }

    let tempFun = (_p, _file_type_arr, _sorting) => {
      let tempFilesArr = fs.readdirSync(_p);
      for (let i = 0; i < tempFilesArr.length; i++) {
        const file_item = tempFilesArr[i];

        if (file_item == "node_modules") {
          console.error("node_modules 文件夹跳过");
          continue;
        }
        if (file_item.includes("$RECYCLE.BIN")) {
          console.error("垃圾箱文件跳过 $RECYCLE.BIN");
          continue;
        }

        let nowP = path.resolve(_p, file_item);
        if (this.isNotDir(nowP)) {
          tempFun(nowP, _file_type_arr, _sorting);
          continue;
        }

        let t = "";
        try {
          t = file_item.match(/\.\w+$/)[0].split(".")[1];
        } catch (error) {
          // console.error("获取文件类型失败 | Get file type failed");
          continue;
        }

        if (
          !_file_type_arr.length ||
          _file_type_arr.some(
            (item) => String(item).toLowerCase() === String(t).toLowerCase()
          )
        ) {
          let detail = fs.statSync(path.resolve(_p, file_item));
          console.log("push--->", allFiles.length, _p, file_item);
          allFiles.push({
            ...detail,
            name: file_item,
            path: path.resolve(_p, file_item),
            ctimeMs: detail.ctimeMs,
          });
        }
      }
    };

    tempFun(_p, _file_type_arr, _sorting);

    allFiles = index.unique(allFiles, "path");

    allFiles.sort((a, b) => {
      if (_sorting && String(_sorting).toLowerCase() === "asc") {
        return a.ctimeMs - b.ctimeMs;
      } else {
        return b.ctimeMs - a.ctimeMs;
      }
    });
    return allFiles;
  },
  /**
   * 铺某条路径，若路径不存在则一步步创建
   * @param {路径} p
   */
  make_path(p) {
    if (!p | (Object.prototype.toString.call(p) !== "[object String]")) {
      console.error("请输入字符串路径 | Enter a string path");
      return;
    }
    let _p = path.resolve(p);
    if (fs.existsSync(_p)) {
      console.log("此路径存在 | The path exist");
      return;
    } else {
      console.log("此路径不存在 | The path dose not exist");
    }

    let re = /(\\|\/)/g;
    let p_arr = _p.replace(re, "|").split("|");
    // console.log("p_arr--->", p_arr.length)

    for (let i = 0; i < p_arr.length; i++) {
      const item_p = p_arr.filter((_, j) => j <= i);
      let p = path.resolve("/", ...item_p);
      if (!fs.existsSync(p)) {
        fs.mkdirSync(p);
      }
    }
  },
  // 人家原生的之前就有递归创建文件夹的API
  makePath(p) {
    return new Promise((resolve) => {
      fs.mkdir(p, { recursive: true }, (err) => {
        if (err) {
          resolve(false);
          throw err;
        } else {
          resolve(true);
        }
      });
    });
  },
  /**
   * 图片转base64返回字符串，可直接使用在img的stc中
   * @param {图片链接地址} _img_path
   * @returns
   */
  img_2_base64(_img_path) {
    try {
      let p = fs.readFileSync(_img_path);
      let res_str = new Buffer.from(p).toString("base64");
      return `data:image/png;base64,${res_str}`;
    } catch (error) {
      console.error("发现未知问题 | Discover unknow issues");
      return "";
    }
  },
  /**
   * 批量 图片 转换 base64 文件
   * @param {文件路径} o_data_path
   * @param {生成的base64存放地址} target_data_path
   * @param {需要匹配的文件类型} all_pic_type
   */
  imgs_2_base64s(o_data_path, target_data_path, all_pic_type = ["jpg", "png"]) {
    let all_pic = fs.readdirSync(path.resolve(o_data_path));
    all_pic.forEach((item) => {
      let str = "",
        file_name = "";
      try {
        let re = /\.\w+$/;
        str = item.match(re)[0].substring(1);
        file_name = item.split(str)[0].substring(0, -1);
      } catch (error) {}
      if (all_pic_type.includes(String(str).toLowerCase())) {
        let p = fs.readFileSync(path.resolve(o_data_path, item));
        let base64str = new Buffer.from(p).toString("base64");
        fs.writeFileSync(
          path.resolve(target_data_path, "结果img标签" + file_name + ".html"),
          `<img src="data:image/png;base64,${base64str}" />`,
          "utf-8"
        );
      }
    });
  },
  // 网页图片转换base64
  httpImg2Base64(imgPath) {
    return new Promise((resolve) => {
      axios
        .get(imgPath, { responseType: "arraybuffer" })
        .then((response) => {
          const base64Image = Buffer.from(response.data, "binary").toString(
            "base64"
          );
          fs.writeFileSync("catchImgxxx.txt", base64Image, "utf-8");
          let res = fs.readFileSync("catchImgxxx.txt", "utf-8");
          resolve("data:image/png;base64," + res);
          fs.unlinkSync("catchImgxxx.txt");
        })
        .catch((error) => {
          console.error(error);
          resolve("");
        });
    });
  },
  // base64 转 png
  downLoadImgByBase64(base64String, targetDirPath, targetName) {
    if (!base64String) {
      console.error("请输入图片下载链接");
      return;
    }
    if (!this.checkDirExist(targetDirPath)) {
      console.error("文件夹路径不对");
      return;
    }
    if (!targetName) {
      console.error("请输入文件名");
      return;
    }

    return new Promise((resolve) => {
      // 提取Base64编码部分（去除前缀）
      const dataUrlRegex = /^data:(.*);base64,(.*)$/;
      const matches = base64String.match(dataUrlRegex);
      if (matches) {
        const imageData = Buffer.from(matches[2], "base64");

        // 生成临时文件名
        const tempFileName = `temp_${Date.now()}.png`;

        // 写入临时文件
        fs.writeFileSync(path.resolve(targetDirPath, targetName), imageData);
        resolve(true);
        console.log(`已将Base64转换为PNG图像并保存至 ${tempFileName}`);
      } else {
        console.error("无效的Base64字符串");
        resolve(false);
      }
    });
  },
  // 判断文件夹路径是否存在
  checkDirExist(path) {
    return fs.existsSync(path);
  },
  // 通过连接下载图片 TODO 试了下需要 先转base64 才行 后面若有好办法再说
  downLoadImgByUrl(imgUrl, targetDirPath, targetName) {
    if (!imgUrl) {
      console.error("请输入图片下载链接");
      return;
    }
    if (!this.checkDirExist(targetDirPath)) {
      console.error("文件夹路径不对");
      return;
    }
    if (!targetName) {
      console.error("请输入文件名");
      return;
    }
    return new Promise(async (resolve) => {
      let base64Str = await this.httpImg2Base64(imgUrl);
      try {
        let flag = await this.downLoadImgByBase64(
          base64Str,
          targetDirPath,
          targetName
        );
        resolve(flag);
      } catch (error) {
        resolve(false);
      }
    });
  },
  // 找出文件中的所有注释 删除其 存在新的文件
  // 一个简单的http服务
  http_server() {
    let server = http.createServer(function (request, response) {
      let url = request.url;
      if (url === "/") {
        response.writeHead(200, { "Content-Type": "text/html" });
        response.end("Hello World");
      } else if (url === "/test") {
        response.writeHead(200, { "Content-Type": "text/html" });
        response.end("Hi im test");
      }
    });
    server.listen(7788);
    console.log("Server is running at http://127.0.0.1:7788");
  },
};

module.exports = node_funs;
